package net.chenlin.dp.ids.client.util;

import net.chenlin.dp.ids.common.util.JsonUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * http工具类
 * @author zcl<yczclcn@163.com>
 */
public class HttpUtil {

    /**
     * get请求，参数通过map拼接
     * @param uri
     * @param param
     * @return
     */
    public static String doGet(String uri, Map<String, Object> param) {
        StringBuilder paramBuilder = new StringBuilder(uri);
        paramBuilder.append("?");
        for (Map.Entry<String, Object> nameValuePair : param.entrySet()) {
            paramBuilder.append(nameValuePair.getKey()).append("=").append(nameValuePair.getValue()).append("&");
        }
        String requestUri = paramBuilder.substring(0, paramBuilder.length()-1);
        return doGet(requestUri);
    }

    /**
     * get请求，参数通过链接拼接
     * @param uri
     * @return
     */
    public static String doGet(String uri) {
        HttpGet httpGet = new HttpGet(uri);
        return sendRequest(httpGet);
    }

    /**
     * post请求发送form数据
     * @param uri
     * @param param
     * @return
     */
    public static String doPost(String uri, Map<String, Object> param) {
        List<NameValuePair> nameValuePairList = new ArrayList<>(param.size());
        BasicNameValuePair nameValuePair;
        for (Map.Entry<String, Object> entry : param.entrySet()) {
            nameValuePair = new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue()));
            nameValuePairList.add(nameValuePair);
        }
        try {
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8");
            return post(uri, formEntity);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * post请求发送json数据
     * @param uri
     * @param obj
     * @return
     */
    public static String doPost(String uri, Object obj) {
        String jsonParam = JsonUtil.toStr(obj);
        StringEntity stringEntity = new StringEntity(jsonParam, "utf-8");
        stringEntity.setContentType("application/json; charset=utf-8");
        return post(uri, stringEntity);
    }

    /**
     * post请求
     * @param uri
     * @param postParam
     * @return
     */
    private static String post(String uri, HttpEntity postParam) {
        HttpPost httpPost = new HttpPost(uri);
        httpPost.setEntity(postParam);
        return sendRequest(httpPost);
    }

    /**
     * 发送请求
     * RequestConfig:连接目标url最大超时时间，等待响应最大超时时间，从连接池获取可用连接最大超时时间
     * CloseableHttpClient:最大连接总数，分配给同一个route的最大并发数
     * @param request
     * @return
     */
    private static String sendRequest(HttpUriRequest request) {
        RequestConfig config = RequestConfig.custom()
                .setConnectTimeout(1000)
                .setSocketTimeout(10000)
                .setConnectionRequestTimeout(500).build();
        CloseableHttpClient client = HttpClientBuilder.create()
                .setMaxConnTotal(1000)
                .setMaxConnPerRoute(1000)
                .setDefaultRequestConfig(config).build();
        try {
            CloseableHttpResponse response = client.execute(request);
            HttpEntity responseEntity = response.getEntity();
            if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                return EntityUtils.toString(responseEntity, "utf-8");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}
